package csfd;

import data.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.persistence.*;

/**
 *
 * @author Michal Hanzlik, Tomas Jiran
 */
public class CSFD {
    private static EntityManager em;
    private static EntityTransaction tx;
    public static Uzivatel loggedUser;
    private static java.sql.Date datum_narozeni;
    private static int key;

    public static void init() {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("CSFDPU");
        em = emf.createEntityManager();
        tx = em.getTransaction();
    }

    public static void close() {
        em.close();
    }

    /**
     * Zkontroluje, jestli existuje v DB uživatel s danými udaji.
     */
    public static boolean chceckLogin(String login, String pass) {
        TypedQuery queryS = em.createQuery("SELECT u FROM Uzivatel u WHERE u.login=:login AND u.heslo =:heslo", Uzivatel.class);
        queryS.setParameter("login", login);
        queryS.setParameter("heslo", pass);

        try {
            loggedUser = (Uzivatel) queryS.getSingleResult();
            return true;
        } catch (NoResultException nre) {
            // Nexistuje žádný uživatel s tímto loginem. A proto ho mužu vytvořit.
            return false;
        } catch (NonUniqueResultException nurx) {
            // Bylo vráceno více výsledků, takže uživatelů s tímto loginem a heslem je více.
            System.out.println("Bylo vráceno více výsledků, takže uživatelů s tímto loginem a heslem je více.");
            System.out.println(nurx.getMessage());
            return false;
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return false;
        }
    }

    public static String encrypt(String password) {
        String result = "";
        for (int i = 0; i < password.length(); i++) {
            result += (int) password.charAt(i) + i * key;
        }
        return result;
    }

    /**
     * Zkontroluje, jestli existuje v DB pridavany film
     */
    public static boolean checkNewFilm(String nazev, String rokStr) {
        Film film;
        int rok = Integer.parseInt(rokStr);
        TypedQuery queryS = em.createQuery("SELECT f FROM Film f WHERE f.nazev_filmu=:nazev_filmu AND f.rok =:rok", Film.class);
        queryS.setParameter("nazev_filmu", nazev);
        queryS.setParameter("rok", rok);

        try {
            film = (Film) queryS.getSingleResult();
            return true;
        } catch (NoResultException nre) {
            // Nexistuje žádný takovy film v db. A proto ho mužu vytvořit.
            return false;
        } catch (NonUniqueResultException nurx) {
            System.out.println(nurx.getMessage());
            return false;
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return false;
        }
    }

    public static boolean addNewFilm(String nazev, String nazevOrig, String rok,
            String delka, java.util.List staty, java.util.List zanry, java.util.List reziseri, java.util.List herci) {
        try {
            Film film = new Film();
            film.setNazev_filmu(nazev);
            film.setNazev_orig(nazevOrig);
            film.setRok(Integer.parseInt(rok));
            film.setDelka(Integer.parseInt(delka));
            film.setStaty(staty);
            film.setZanry(zanry);
            film.setReziseri(reziseri);
            film.setHerci(herci);
            film.setOwner(loggedUser);

            tx.begin();
            em.persist(film);
            tx.commit();
            return true;
        } catch (Exception e) {
            System.out.println("ERORR");
            System.out.println(e.getMessage());
            return false;
        }
    }

    public static boolean checkNewZanr(String nazev) {
        Zanr zanr;
        TypedQuery queryS = em.createQuery("SELECT z FROM Zanr z WHERE z.nazev_zanru=:nazev_zanru", Zanr.class);
        queryS.setParameter("nazev_zanru", nazev);

        try {
            zanr = (Zanr) queryS.getSingleResult();
            return true;
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return false;
        }
    }

    public static boolean checkNewStat(String nazev) {
        Stat stat;
        TypedQuery queryS = em.createQuery("SELECT s FROM Stat s WHERE s.nazev_statu=:nazev_statu", Stat.class);
        queryS.setParameter("nazev_statu", nazev);

        try {
            stat = (Stat) queryS.getSingleResult();
            return true;
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return false;
        }
    }

    public static boolean checkNewHerec(String jmeno, String prijmeni, String datum) {
        Herec herec;
        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
        java.util.Date utilDatum;
        try {
            utilDatum = sdf.parse(datum);
        } catch (ParseException e) {
            System.out.println(e.getMessage());
            return false;
        }
        datum_narozeni = new java.sql.Date(utilDatum.getTime());

        TypedQuery queryS = em.createQuery("SELECT h FROM Herec h WHERE h.jmeno=:jmeno AND h.prijmeni=:prijmeni AND h.datum_narozeni=:datum_narozeni", Herec.class);
        queryS.setParameter("jmeno", jmeno);
        queryS.setParameter("prijmeni", prijmeni);
        queryS.setParameter("datum_narozeni", datum_narozeni);

        try {
            herec = (Herec) queryS.getSingleResult();
            return true;
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return false;
        }
    }

    public static boolean checkNewReziser(String jmeno, String prijmeni) {
        Reziser reziser;
        TypedQuery queryS = em.createQuery("SELECT r FROM Reziser r WHERE r.jmeno=:jmeno AND r.prijmeni=:prijmeni", Reziser.class);
        queryS.setParameter("jmeno", jmeno);
        queryS.setParameter("prijmeni", prijmeni);

        try {
            reziser = (Reziser) queryS.getSingleResult();
            return true;
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return false;
        }
    }

    public static boolean addNewZanr(String nazev, String charakteristika) {
        try {
            Zanr zanr = new Zanr();
            zanr.setNazev_zanru(nazev);
            zanr.setCharakteristika(charakteristika);

            tx.begin();
            em.persist(zanr);
            tx.commit();
            return true;
        } catch (Exception e) {
            System.out.println("ERORR");
            System.out.println(e.getMessage());
            return false;
        }
    }

    public static boolean addNewStat(String nazev) {
        try {
            Stat stat = new Stat();
            stat.setNazev_statu(nazev);

            tx.begin();
            em.persist(stat);
            tx.commit();
            return true;
        } catch (Exception e) {
            System.out.println("ERORR");
            System.out.println(e.getMessage());
            return false;
        }
    }

    public static boolean addNewHerec(String jmeno, String prijmeni) {
        try {
            Herec herec = new Herec();
            herec.setJmeno(jmeno);
            herec.setPrijmeni(prijmeni);
            herec.setDatum_narozeni(datum_narozeni); // hodnota uz je nastavena z medody checkNewHerec()            

            tx.begin();
            em.persist(herec);
            tx.commit();
            return true;
        } catch (Exception e) {
            System.out.println("ERORR");
            System.out.println(e.getMessage());
            return false;
        }
    }

    public static boolean addNewReziser(String jmeno, String prijmeni, String popis) {
        try {
            Reziser reziser = new Reziser();
            reziser.setJmeno(jmeno);
            reziser.setPrijmeni(prijmeni);
            reziser.setPopis(popis);

            tx.begin();
            em.persist(reziser);
            tx.commit();
            return true;
        } catch (Exception e) {
            System.out.println("ERORR");
            System.out.println(e.getMessage());
            return false;
        }
    }

    public static boolean addNewComment(Komentar comment) {
        try {
            tx.begin();
            em.persist(comment);
            tx.commit();
            return true;
        } catch (Exception e) {
            System.out.println("ERORR");
            System.out.println(e.getMessage());
            return false;
        }
    }

    public static boolean deleteComment(Komentar kom/*String login, String text, Film currentFilm*/) {
        tx.begin();
        em.remove(kom);
        tx.commit();
        return true;
    }

    /**
     * Ulozit noveho uzivatele do DB.
     */
    public static boolean registrNewUser(String name, String surname, String login, String pass, String email) {

//        System.out.println("********************");
//        System.out.println("*  Dynamic Queries *");
//        System.out.println("********************");

        TypedQuery queryS = em.createQuery("SELECT u FROM Uzivatel u WHERE u.login=:login", Uzivatel.class);
        queryS.setParameter("login", login);
        Uzivatel u;
        System.out.println("vytvářím...");
        try {
            u = (Uzivatel) queryS.getSingleResult();
            System.out.println(u.getLogin());
            return false;
        } catch (NoResultException nre) {
            // Nexistuje žádný uživatel s tímto loginem. A proto ho mužu vytvořit.
            Uzivatel user = new Uzivatel();
            user.setJmeno(name);
            user.setPrijmeni(surname);
            user.setLogin(login);
            user.setHeslo(pass);
            user.setEmail(email);
            user.setCreated(new Date());

            tx.begin();
            em.persist(user);
            tx.commit();
            return true;
        } catch (NonUniqueResultException nurx) {
            // Bylo vráceno více výsledků, takže uživatelů s tímto loginem je více.
            System.out.println("Bylo vráceno více výsledků, takže uživatelů s tímto loginem je více.");
            System.out.println(nurx.getMessage());
            return false;
        } catch (Exception e) {
            System.out.println("ERORR");
            System.out.println(e.getMessage());
            return false;
        }
    }

    public static boolean evaluated_already(Film currentFilm) {
        Hodnoceni hod;
        TypedQuery queryS = em.createQuery("SELECT h FROM Hodnoceni h WHERE h.id_osoby=:id_osoby AND h.id_filmu=:id_filmu", Hodnoceni.class);
        queryS.setParameter("id_osoby", loggedUser.getId_osoby());
        queryS.setParameter("id_filmu", currentFilm.getId_filmu());
        try {
            hod = (Hodnoceni) queryS.getSingleResult();
            return true;
        } catch (NoResultException nre) {
            return false;
        } catch (Exception e) {
            System.out.println("ERORR");
            System.out.println(e.getMessage());
            return true;
        }
    }

    public static void evaluation(Film currentFilm, int ohodnoceni) {
        Hodnoceni h = new Hodnoceni();
        h.setId_filmu(currentFilm.getId_filmu());
        h.setId_osoby(loggedUser.getId_osoby());
        h.setFilm(currentFilm);
        h.setUzivatel(loggedUser);
        h.setHodnotil(ohodnoceni);
        currentFilm.setOhodnoceni(ohodnoceni);

        tx.begin();
        em.persist(h);
        tx.commit();
    }

    /**
     * Ulozi nove udaj uzivatele s loginem predanem v parametru do DB.
     */
    public static boolean editUser(String name, String surname, String login, String pass, String email) {

//        System.out.println("********************");
//        System.out.println("*  Dynamic Queries *");
//        System.out.println("********************");

        TypedQuery queryS = em.createQuery("SELECT u FROM Uzivatel u WHERE u.login=:login", Uzivatel.class);
        queryS.setParameter("login", login);
        Uzivatel user;
        try {
            user = (Uzivatel) queryS.getSingleResult();

            user.setJmeno(name);
            user.setPrijmeni(surname);
            user.setLogin(login);
            user.setHeslo(pass);
            user.setEmail(email);

            tx.begin();
            em.persist(user);
            tx.commit();
            return true;
        } catch (NoResultException nre) {
            // Nexistuje žádný uživatel s tímto loginem. A proto ho mužu vytvořit.

            return false;
        } catch (NonUniqueResultException nurx) {
            // Bylo vráceno více výsledků, takže uživatelů s tímto loginem je více.
            System.out.println("Bylo vráceno více výsledků, takže uživatelů s tímto loginem je více.");
            System.out.println(nurx.getMessage());
            return false;
        } catch (Exception e) {
            System.out.println("ERORR");
            System.out.println(e.getMessage());
            return false;
        }
    }

    public static java.util.List getFilmsByUser(String login) {
        TypedQuery queryS = em.createQuery("SELECT f FROM Film f WHERE f.owner.login=:login", Uzivatel.class);
        queryS.setParameter("login", login);
        return queryS.getResultList();
    }

    public static java.util.List getCommentsByUser(String login) {
        TypedQuery queryS = em.createQuery("SELECT k FROM Komentar k WHERE k.owner.login=:login", Komentar.class);
        queryS.setParameter("login", login);
        return queryS.getResultList();
    }

    public static java.util.List getCommentsByFilm(Film film) {
        TypedQuery queryS = em.createQuery("SELECT k FROM Komentar k WHERE k.film=:film", Komentar.class);
        queryS.setParameter("login", film);
        return queryS.getResultList();
    }

    public static java.util.List getAllZanry() {
        TypedQuery queryS = em.createQuery("SELECT z FROM Zanr z", Zanr.class);
        return queryS.getResultList();
    }

    public static java.util.List getAllStaty() {
        TypedQuery queryS = em.createQuery("SELECT s FROM Stat s", Stat.class);
        return queryS.getResultList();
    }

    public static java.util.List getAllReziseri() {
        TypedQuery queryS = em.createQuery("SELECT r FROM Reziser r", Reziser.class);
        return queryS.getResultList();
    }

    public static java.util.List getAllHerci() {
        TypedQuery queryS = em.createQuery("SELECT h FROM Herec h", Herec.class);
        return queryS.getResultList();
    }

    public static java.util.List findFilmByName(String name) {
        TypedQuery queryS = em.createQuery("SELECT f FROM Film f WHERE f.nazev_filmu LIKE :nazev_filmu OR f.nazev_orig LIKE :nazev_orig", Film.class);
        String likeName = "%" + name + "%";
        queryS.setParameter("nazev_filmu", likeName);
        queryS.setParameter("nazev_orig", likeName);
        return queryS.getResultList();
    }
}